package cn.lzd.ui.widgets;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.*;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatImageView;
import cn.lzd.ui.R;

/**
 * 圆角 ImageView，四个圆角大小可控
 */
public class RoundImageView extends AppCompatImageView {

    /**
     * 圆角大小
     */
    private int mRadius;

    /**背景图片*/
    private Bitmap mSrc;

    /**
     * 是否使用裁剪
     */
    private boolean useCenterCrop;

    private final Rect srcRect = new Rect();
    private final RectF dstRectF = new RectF();
    private final Path srcPath = new Path();
    // region 圆角相关
    // 左上、右上、右下、左下
    private final int[] realRadius = new int[4];
    private final RectF[] radiusRects = new RectF[] {
            new RectF(), new RectF(), new RectF(), new RectF()
    };
    // endregion
    private Bitmap target;

    public RoundImageView(Context context) {
        this(context,null);
    }

    public RoundImageView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    @SuppressLint("NonConstantResourceId")
    public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);
        TypedArray arr = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyleAttr, 0);
        int indexCount = arr.getIndexCount();
        for (int i = 0; i < indexCount; i++) {
            int index = arr.getIndex(i);
            if (index == R.styleable.RoundImageView_riv_imageSrc) {
                mSrc = BitmapFactory.decodeResource(getResources(), arr.getResourceId(index, 0));
            } else if (index == R.styleable.RoundImageView_riv_radius) {
                mRadius = arr.getDimensionPixelSize(index, 0);
            } else if (index == R.styleable.RoundImageView_riv_useCenterCrop) {
                useCenterCrop = arr.getBoolean(index, false);
            } else if (index == R.styleable.RoundImageView_riv_ltRadius) {
                realRadius[0] = arr.getDimensionPixelSize(index, 0);
            } else if (index == R.styleable.RoundImageView_riv_rtRadius) {
                realRadius[1] = arr.getDimensionPixelSize(index, 0);
            } else if (index == R.styleable.RoundImageView_riv_rbRadius) {
                realRadius[2] = arr.getDimensionPixelSize(index, 0);
            } else if (index == R.styleable.RoundImageView_riv_lbRadius) {
                realRadius[3] = arr.getDimensionPixelSize(index, 0);
            }
        }
        arr.recycle();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mSrc != null){
            if (target == null || target.isRecycled()) {
                int width = getWidth(), height = getHeight();
                if (width <= 0 || height <= 0) {
                    return;
                }
                createRoundImage(mSrc, width, height);
            }
            canvas.drawBitmap(target,0,0,null);//绘制圆角背景
            target.recycle();
            target = null;
        }
    }

    private void createRoundImage(Bitmap mSrc, int width, int height) {
        target = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);
        dstRectF.set(0, 0, width, height);

        int srcWidth = mSrc.getWidth();
        int srcHeight = mSrc.getHeight();
        float srcRatio = (float) srcWidth / srcHeight;
        float dstRatio = (float) width / height;

        //绘制圆角矩形
        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        formatRadius(width, height);
        initSrcPath(canvas, paint, width, height);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//该模式可以让两个重叠,并取交集

        //绘制图片
        if (useCenterCrop) {
            if (srcRatio > dstRatio) {
                int offsetX = (int) ((srcWidth - srcHeight * dstRatio) / 2);
                srcRect.set(offsetX, 0, srcWidth - offsetX, srcHeight);
            } else {
                int offsetY = (int) ((srcHeight - srcWidth / dstRatio) / 2);
                srcRect.set(0, offsetY, srcWidth, srcHeight - offsetY);
            }
        } else {
            srcRect.set(0, 0, srcWidth, srcHeight);
        }
        canvas.drawBitmap(mSrc, srcRect, dstRectF, paint);
    }

    /**
     * 格式化圆角数据 -> 四个单独设定的圆角优先级更高，其次是 mRadius
     */
    private void formatRadius(int width, int height) {
        for (int i = 0; i < realRadius.length; i++) {
            realRadius[i] = realRadius[i] == 0 ? mRadius : realRadius[i];
        }
        radiusRects[0].set(0, 0, realRadius[0] * 2, realRadius[0] * 2);
        radiusRects[1].set(width - realRadius[1] * 2, 0, width, realRadius[1] * 2);
        radiusRects[2].set(width - realRadius[2] * 2, height - realRadius[2] * 2, width, height);
        radiusRects[3].set(0, height - realRadius[3] * 2, realRadius[3] * 2, height);
    }

    /**
     * 初始化绘制路径
     */
    private void initSrcPath(Canvas canvas, Paint paint, int width, int height) {
        this.srcPath.reset();
        canvas.drawArc(radiusRects[0], 180, 90, true, paint);
        canvas.drawArc(radiusRects[1], 270, 90, true, paint);
        canvas.drawArc(radiusRects[2], 0, 90, true, paint);
        canvas.drawArc(radiusRects[3], 90, 90, true, paint);
        // 绘制剩余图形
        srcPath.moveTo(0, realRadius[0]);
        srcPath.moveTo(realRadius[0], realRadius[0]);
        srcPath.moveTo(realRadius[0], 0);
        srcPath.lineTo(width - realRadius[1], 0);
        srcPath.lineTo(width - realRadius[1], realRadius[1]);
        srcPath.lineTo(width, realRadius[1]);
        srcPath.lineTo(width, height - realRadius[2]);
        srcPath.lineTo(width - realRadius[2], height - realRadius[2]);
        srcPath.lineTo(width - realRadius[2], height);
        srcPath.lineTo(realRadius[3], height);
        srcPath.lineTo(realRadius[3], height - realRadius[3]);
        srcPath.lineTo(0, height - realRadius[3]);
        srcPath.lineTo(0, realRadius[0]);
        srcPath.close();
        canvas.drawPath(srcPath, paint);
    }

    /**
     * 设置图片，需要保证是 BitMap
     */
    public void setImgResource(int resId){
        this.mSrc = BitmapFactory.decodeResource(getResources(), resId);
        invalidate();
    }

    /**
     * 设置图片
     */
    public void setBitmap(Bitmap bitmap) {
        this.mSrc = bitmap;
        invalidate();
    }

    /**
     * 设置圆角，四个角一起设置。优先级低于 {@link RoundImageView#setRadius(int, int, int, int)}
     */
    public void setRadius(int radiusPx) {
        mRadius = radiusPx;
        invalidate();
    }

    /**
     * 设置圆角尺寸
     * @param ltRadius 左上
     * @param rtRadius 右上
     * @param rbRadius 右下
     * @param lbRadius 左下
     */
    public void setRadius(int ltRadius, int rtRadius, int rbRadius, int lbRadius) {
        realRadius[0] = ltRadius;
        realRadius[1] = rtRadius;
        realRadius[2] = rbRadius;
        realRadius[3] = lbRadius;
        invalidate();
    }

    /**
     * 设置是否使用裁剪
     * 如果使用裁剪，那么将不会缩放，会将长和宽较小的一方等比撑满，剩余的部分会被裁剪
     * 如果不使用裁剪，将会通过拉伸将图片完整展示
     */
    public void setUseCenterCrop(boolean useCenterCrop) {
        this.useCenterCrop = useCenterCrop;
        invalidate();
    }
}